/*
 * @lc app=leetcode.cn id=641 lang=typescript
 *
 * [641] 设计循环双端队列
 */

// @lc code=start
class MyCircularDeque {
  queue: number[];
  head: number;
  tail: number;
  constructor(k: number) {
    this.queue = new Array(k + 1);
    this.head = 0;
    this.tail = 0;
  }

  insertFront(value: number): boolean {
    if (this.isFull()) return false;
    this.queue[this.head] = value;
    this.head = (this.head - 1 + this.queue.length) % this.queue.length;
    return true;
  }

  insertLast(value: number): boolean {
    if (this.isFull()) return false;
    this.tail = (this.tail + 1) % this.queue.length;
    this.queue[this.tail] = value;
    return true;
  }

  deleteFront(): boolean {
    if (this.isEmpty()) return false;
    this.head = (this.head + 1) % this.queue.length;
    return true;
  }

  deleteLast(): boolean {
    if (this.isEmpty()) return false;
    this.tail = (this.tail - 1 + this.queue.length) % this.queue.length;
    return true;
  }

  getFront(): number {
    if (this.isEmpty()) return -1;
    return this.queue[(this.head + 1) % this.queue.length];
  }

  getRear(): number {
    if (this.isEmpty()) return -1;
    return this.queue[(this.tail + this.queue.length) % this.queue.length];
  }

  isEmpty(): boolean {
    return this.head === this.tail;
  }

  isFull(): boolean {
    return (this.tail + 1) % this.queue.length === this.head;
  }
}

/**
 * Your MyCircularDeque object will be instantiated and called as such:
 * var obj = new MyCircularDeque(k)
 * var param_1 = obj.insertFront(value)
 * var param_2 = obj.insertLast(value)
 * var param_3 = obj.deleteFront()
 * var param_4 = obj.deleteLast()
 * var param_5 = obj.getFront()
 * var param_6 = obj.getRear()
 * var param_7 = obj.isEmpty()
 * var param_8 = obj.isFull()
 */
// @lc code=end
